/**
 * 
 */
package com.gragra.wilsHandler;
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
/**
 * @author Christoph Teichmann
 * created Nov 20, 2013 10:13:49 PM
 * @version 0.1
 */
public class ComputeMultipleScores
{
	/**
	 * 
	 *
	 * @param val
	 * @return
	 */
	private static double roundToTwo(double val)
	{
		val *= 100.0;
		val = Math.round(val);
		return val/100.0;
	}
	/**
	 *
	 * @param args
	 * @throws IOException 
	 */
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws IOException
	{
		StringBuffer header = new StringBuffer();
		for(int i=1;i<args.length;i+=2)
		{
			String gold = args[i];
			File folder = new File(args[i+1]);
			String[] parts = folder.list();
			TreeMap<String, Object[]> m = new TreeMap<String, Object[]>();
			for(String part : parts)
			{
				String[] elems = part.split("_");
				String alg = elems[1];
				String type = elems[2];
				Object[] pair = m.get(alg);
				if(pair == null)
				{
					pair = new Object[] {gold,new ArrayList<String>(),new ArrayList<String>()};
					m.put(alg,pair);
				}
				if(type.matches("best"))
				{((ArrayList<String>) pair[1]).add(args[i+1]+part);}
				if(type.matches("samp"))
				{((ArrayList<String>) pair[2]).add(args[i+1]+part);}
			}
			if(i==1)
			{
				header.append("Language");
				for(Map.Entry<String, Object[]> ent : m.entrySet())
				{
					header.append(";"+ent.getKey()+" best UAS");
					header.append(";"+ent.getKey()+" best UUAS");
					header.append(";"+ent.getKey()+" samp UAS");
					header.append(";"+ent.getKey()+" samp UUAS");
				}
			}
			header.append("\r\n");
			String lang = gold.split("/")[1];
			header.append(lang);
			for(Map.Entry<String, Object[]> ent : m.entrySet())
			{
				DoubleArrayList accs = new DoubleArrayList();
				DoubleArrayList unAccs = new DoubleArrayList();
				for(String s : (ArrayList<String>) ent.getValue()[1])
				{
					BufferedReader g = new BufferedReader(new FileReader(gold));
					BufferedReader e = new BufferedReader(new FileReader(s));
					double[] pair = EvaluateDependencyMicroAveraged.main(g, e);
					accs.add(pair[0]);
					unAccs.add(pair[1]);
				}
				
				double mean;
				header.append(";");
				header.append(roundToTwo(mean = makeMean(accs)));
				header.append(" (");
				header.append(roundToTwo(makeVariance(mean, accs)));
				header.append(")");
				header.append(";");
				header.append(roundToTwo(mean = makeMean(unAccs)));
				header.append(" (");
				header.append(roundToTwo(makeVariance(mean, unAccs)));
				header.append(")");
				accs.clear();
				unAccs.clear();
				for(String s : (ArrayList<String>) ent.getValue()[2])
				{
					BufferedReader g = new BufferedReader(new FileReader(gold));
					BufferedReader e = new BufferedReader(new FileReader(s));
					double[] pair = EvaluateDependencyMicroAveraged.main(g, e);
					accs.add(pair[0]);
					unAccs.add(pair[1]);
				}
				header.append(";");
				header.append(roundToTwo(mean = makeMean(accs)));
				header.append(" (");
				header.append(roundToTwo(makeVariance(mean, accs)));
				header.append(")");
				header.append(";");
				header.append(roundToTwo(mean = makeMean(unAccs)));
				header.append(" (");
				header.append(roundToTwo(makeVariance(mean, unAccs)));
				header.append(")");
			}
			BufferedWriter bw = new BufferedWriter(new FileWriter(args[0]));
			bw.write(header.toString());
			bw.close();
		}
	}
	/**
	 * 
	 * @param mean
	 * @param accs
	 * @return
	 */
	private static double makeVariance(double mean, DoubleArrayList accs)
	{
		double ret = 0.0;
		for(int i=0;i<accs.size();++i)
		{ret += Math.abs((accs.getDouble(i)-mean)/mean);}
		return ret/(double) accs.size();
	}
	/**
	 * 
	 * @param accs
	 * @return
	 */
	private static double makeMean(DoubleArrayList accs)
	{
		double ret = 0.0;
		for(int i=0;i<accs.size();++i)
		{ret += accs.getDouble(i);}
		return ret/(double) accs.size();
	}
}